package com.r2coding.music.service.impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.r2coding.common.exception.BizCode;
import com.r2coding.common.exception.ServiceException;
import com.r2coding.music.ExcelSongModel;
import com.r2coding.music.dao.SingerDao;
import com.r2coding.music.dao.SongListDao;
import com.r2coding.music.dao.SongSongListDao;
import com.r2coding.music.entity.SingerEntity;
import com.r2coding.music.entity.SongSongListEntity;
import com.r2coding.music.listener.SongListener;
import com.r2coding.music.vo.req.HandleSongListReqVo;
import com.r2coding.music.vo.req.QuerySongReqVo;
import com.r2coding.music.vo.resp.SongAndSongListRespVo;
import com.r2coding.music.vo.resp.SongRespVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.r2coding.common.util.PageUtils;
import com.r2coding.common.util.Query;

import com.r2coding.music.dao.SongDao;
import com.r2coding.music.entity.SongEntity;
import com.r2coding.music.service.SongService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 歌曲
 *
 * @author 98k灬
 * @email hk666zx@163.com
 * @date 2022-05-04 20:46:11
 */
@Service("songService")
public class SongServiceImpl extends ServiceImpl<SongDao, SongEntity> implements SongService {

    @Autowired
    SongSongListDao songListDao;

    @Autowired
    SingerDao singerDao;

    @Autowired
    SongListDao listDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SongEntity> page = this.page(
                new Query<SongEntity>().getPage(params),
                new QueryWrapper<SongEntity>()
        );
        return new PageUtils(page);
    }

    @Override
    public PageInfo<SongRespVo> getList(QuerySongReqVo vo) {
        PageHelper.startPage(vo.getCurrent(), vo.getSize());
        List<SongRespVo> list = this.baseMapper.getList(vo.getSongName(), vo.getSingerName(), vo.getStatus());
        return new PageInfo<SongRespVo>(list);
    }

    @Override
    public SongRespVo getSongById(Integer id) {
        return this.baseMapper.getSongById(id);
    }

    @Transactional
    @Override
    public void deleteSongById(Integer id) {
        // 删除歌曲信息
        this.baseMapper.deleteById(id);
        // 删除歌曲与歌单关系信息
        songListDao.delete(new QueryWrapper<SongSongListEntity>().eq("song_id", id));
    }

    @Override
    public void saveSong(SongEntity song) {
        song.setDeleted(0);
        song.setUpdateTime(new Date());
        song.setCreateTime(new Date());
        this.baseMapper.insert(song);
    }

    @Override
    public void batchSaveSong(MultipartFile file) {
        SongListener songListener = new SongListener();
        try {
            EasyExcel.read(file.getInputStream(), ExcelSongModel.class, songListener).sheet().doRead();
            List<ExcelSongModel> list = songListener.getList();
            if (CollectionUtils.isEmpty(list)) {
                throw new ServiceException(BizCode.FILE_EMPTY);
            }

            List<SongEntity> collect = list.stream().map(item -> {
                SongEntity song = new SongEntity();
                BeanUtils.copyProperties(item, song);
                // 根据歌手名称查询歌手信息
                List<SingerEntity> singer = singerDao.selectList(new QueryWrapper<SingerEntity>().eq("singer_name", item.getSingerName()));
                if (CollectionUtils.isEmpty(singer)) {
                    throw new ServiceException(BizCode.SINGER_INFO_EMPTY);
                }
                song.setSingerId(singer.get(0).getSingerId());
                try {
                    song.setReleaseTime(new SimpleDateFormat("yyyy-MM-dd").parse(item.getReleaseTime()));
                } catch (ParseException e) {
                    log.error("日期解析失败...");
                    throw new ServiceException(BizCode.UPLOAD_ERROR);
                }
                return song;
            }).collect(Collectors.toList());

            for (SongEntity song : collect) {
                this.saveSong(song);
            }
        } catch (IOException e) {
            throw new ServiceException(BizCode.UPLOAD_ERROR);
        }
    }

    @Override
    public List<SongRespVo> getSongsByCategoryId(Integer id) {
        return this.baseMapper.getSongsByCategoryId(id);
    }

    @Override
    public SongAndSongListRespVo getSongAndSongListBySongId(Integer id) {
        // 查询歌曲信息
        SongEntity songEntity = this.baseMapper.selectById(id);
        SongAndSongListRespVo respVo = new SongAndSongListRespVo();
        BeanUtils.copyProperties(songEntity, respVo);
        // 查询歌曲所在的歌单信息
        List<SongSongListEntity> list = songListDao.selectList(new QueryWrapper<SongSongListEntity>().eq("song_id", songEntity.getId()));
        List<Integer> ids = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            ids = list.stream().map(SongSongListEntity::getSongListId).collect(Collectors.toList());
        }
        respVo.setIds(ids);
        return respVo;
    }

    @Transactional
    @Override
    public void handleSongList(HandleSongListReqVo reqVo) {
        // 将该歌曲名下的所有的歌单全部删除
        songListDao.delete(new QueryWrapper<SongSongListEntity>().eq("song_id", reqVo.getSongId()));
        // 重新添加
        if (!CollectionUtils.isEmpty(reqVo.getSongListIds())) {
            for (Integer id : reqVo.getSongListIds()) {
                SongSongListEntity entity = new SongSongListEntity();
                entity.setSongId(reqVo.getSongId());
                entity.setSongListId(id);
                songListDao.insertSongSongList(entity);
            }
        }
    }
}